package com.buglife.video.convert.util;

import com.xuggle.mediatool.IMediaCoder;
import com.xuggle.mediatool.MediaToolAdapter;
import com.xuggle.mediatool.event.AudioSamplesEvent;
import com.xuggle.mediatool.event.IAddStreamEvent;
import com.xuggle.mediatool.event.IAudioSamplesEvent;
import com.xuggle.mediatool.event.IVideoPictureEvent;
import com.xuggle.mediatool.event.VideoPictureEvent;
import com.xuggle.xuggler.*;

/**
 * @author Harry.Zhang
 *
 */
public class Conversor extends MediaToolAdapter {
    private static long duration;
    /**
     * Set output video width; 
     */
    private static final int VIDEO_WIDTH  = 720;
    /**
     * set out video height
     */
    private static final int VIDEO_HEIGHT = 400;
    /**
     * IVideoResampler:Converts IVideoPicture objects of a given width, height and format to a new width, height or format.
     */
    private IVideoResampler  vsample      = null;
    /**
     * IAudioResampler:Used to resample IAudioSamples to different sample rates or number of channels.
     */
    private IAudioResampler  asample      = null;
    
    public static String percent;
    
    /*
     * According to the given IAddStreamEvent,to decode video's stream and resize its video or its audio. (non-Javadoc)
     * @see com.xuggle.mediatool.MediaToolAdapter#onAddStream(com.xuggle.mediatool.event.IAddStreamEvent)
     */
    @Override
    public void onAddStream(IAddStreamEvent event) {
        int streamIndex = event.getStreamIndex();// Get the stream index.
        IMediaCoder mediaCoder = event.getSource();// Get the source of this event.
        IContainer container = mediaCoder.getContainer();// Get the underlying media IContainer that the IMediaCoder is reading from or writing to.
        duration = container.getDuration();
        IStream stream = container.getStream(streamIndex);// Get the stream at the given position.
        IStreamCoder streamCoder = stream.getStreamCoder();// Get the StreamCoder than can manipulate this stream.
        // According to the given codecType to judge video and audio
        if (streamCoder.getCodecType() == ICodec.Type.CODEC_TYPE_VIDEO) {
            streamCoder.setWidth(VIDEO_WIDTH);
            streamCoder.setHeight(VIDEO_HEIGHT);
        } else if (streamCoder.getCodecType() == ICodec.Type.CODEC_TYPE_AUDIO) {
            streamCoder.setSampleRate(44100);
        }
        super.onAddStream(event);
    }
    
    /*
     * (non-Javadoc)
     * @see com.xuggle.mediatool.MediaToolAdapter#onVideoPicture(com.xuggle.mediatool.event.IVideoPictureEvent)
     */
    @Override
    public void onVideoPicture(IVideoPictureEvent event) {
        IVideoPicture pic = event.getPicture();
        //To get the progress of video conversion
        percent = String.format("%.2f", ((Double.valueOf(pic.getTimeStamp()))*100/duration)) + "%";
        if (vsample == null) {
            vsample = IVideoResampler.make(VIDEO_WIDTH, VIDEO_HEIGHT, pic.getPixelType(), pic.getWidth(), pic.getHeight(), pic.getPixelType());
        }
        IVideoPicture out = IVideoPicture.make(pic.getPixelType(), VIDEO_WIDTH, VIDEO_HEIGHT);
        vsample.resample(out, pic);
        
        IVideoPictureEvent asc = new VideoPictureEvent(event.getSource(), out, event.getStreamIndex());
        super.onVideoPicture(asc);
        out.delete();
    }
    
    /*
     * (non-Javadoc)
     * @see com.xuggle.mediatool.MediaToolAdapter#onAudioSamples(com.xuggle.mediatool.event.IAudioSamplesEvent)
     */
    @Override
    public void onAudioSamples(IAudioSamplesEvent event) {
        IAudioSamples samples = event.getAudioSamples();
        if (asample == null) {
            asample = IAudioResampler.make(2, samples.getChannels(), 44100, samples.getSampleRate());
        }
        if (event.getAudioSamples().getNumSamples() > 0) {
            IAudioSamples out = IAudioSamples.make(samples.getNumSamples(), samples.getChannels());
            asample.resample(out, samples, samples.getNumSamples());
            
            AudioSamplesEvent asc = new AudioSamplesEvent(event.getSource(), out, event.getStreamIndex());
            super.onAudioSamples(asc);
            out.delete();
        }
    }
}

